########################################################################
#  Searx-qt - Lightweight desktop application for SearX.
#  Copyright (C) 2020  CYBERDEViL
#
#  This file is part of Searx-qt.
#
#  Searx-qt is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  Searx-qt is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
########################################################################


from searxqt.core.handler import NetworkTypes
from searxqt.core.instanceVersions import (
    parseVersionString,
    InstanceVersionGtEqCmp,
    InstanceVersionTypes
)


def upgradeProfileConfig(profileSettings):
    """
    @param profileSettings: Profile settings to possible upgrade.
    @type profileSettings: QSettings
    """

    # Update from 0.2 to 0.3 (0.2 doesn't have the version defined in the
    # config)
    confVersion = profileSettings.value('version', "", str)
    if not confVersion:
        upgrade_from_0_2_to_0_3(profileSettings)

    return profileSettings


def upgrade_from_0_2_to_0_3(profileSettings):
    """ Migration from version 0.2 to 0.3
    """

    """ Instance filter changes
    """
    instanceFilterConf = profileSettings.value('instanceFilter', dict(), dict)
    if instanceFilterConf:
        """ Version filter changes
        'instanceFilter' 'version' changed from a list with version strings to:
        {
            'min': '',
            'git': True,
            'unknown': False
        }
        """
        # Get old minimum set version (if set)
        oldVersionFilter = instanceFilterConf.get('version', [])
        newMinString = ''
        if oldVersionFilter:
            oldLowestVersion = parseVersionString('100.0.0')
            for oldVersion in oldVersionFilter:
                versionObj = parseVersionString(oldVersion)

                if versionObj.type == InstanceVersionTypes.No:
                    continue

                if InstanceVersionGtEqCmp(oldLowestVersion, versionObj):
                    oldLowestVersion = versionObj

            newMinString = str(oldLowestVersion)

        # Set new config
        instanceFilterConf.update({
            'version': {
                'min': newMinString,
                'git': True,
                'unknown': False
            }
        })

        """ Blacklist structure changes

        From a list with url's to a dict with as key the url and as value a
        tuple with as first value the date (uint) and second value the reason
        (str).

        Also the key changed from `skipUrl` to `blacklist`.
        """
        oldBlacklist = instanceFilterConf.get('skipUrl', [])
        newBlacklist = {}
        for instanceUrl in oldBlacklist:
            newBlacklist.update({instanceUrl: (0, '')})
        instanceFilterConf.update({'blacklist': newBlacklist})
        del oldBlacklist

        """ Whitelist key changed from `url` to `whitelist`
        """
        oldWhitelist = instanceFilterConf.get('url', [])
        instanceFilterConf.update({'whitelist': oldWhitelist})

        """ Network filter changes
        """
        web = False
        tor = False
        i2p = False

        skipExtList = instanceFilterConf.get('skipExt', [])
        extList = instanceFilterConf.get('ext', [])

        # Nothing is checked
        if not extList and not skipExtList:
            web = True
            tor = True
            i2p = True
        # Only web checked
        elif 'onion' in skipExtList and 'i2p' in skipExtList:
            web = True
        # Web + Tor
        elif 'i2p' in skipExtList and not extList:
            web = True
            tor = True
        # Web + i2p
        elif 'onion' in skipExtList and not extList:
            web = True
            i2p = True
        # Tor + i2p
        elif 'onion' in extList and 'i2p' in extList:
            tor = True
            i2p = True
        # Tor
        elif 'onion' in extList:
            tor = True
        # i2p
        elif 'i2p' in extList:
            i2p = True

        # Remove old keys
        if 'skipExt' in instanceFilterConf:
            del instanceFilterConf['skipExt']
        if 'ext' in instanceFilterConf:
            del instanceFilterConf['ext']

        newValue = []
        if web:
            newValue.append(NetworkTypes.Web)
        if tor:
            newValue.append(NetworkTypes.Tor)
        if i2p:
            newValue.append(NetworkTypes.I2P)

        # Set new config
        instanceFilterConf.update({
            'networkTypes': newValue
        })

        profileSettings.setValue('instanceFilter', instanceFilterConf)

    """ Instances data
    """
    handlerData = profileSettings.value('data', dict(), dict)
    instancesData = handlerData.get('instances', {})
    if instancesData:
        """ Network type changes
        """
        for url, instanceData in instancesData.items():
            instanceData['network_type'] = NetworkTypes.netTypeFromUrl(url)

        profileSettings.setValue('data', handlerData)

    profileSettings.setValue('version', "0.3")
